#ifndef OPENHITLS_KAE_RSA_H
#define OPENHITLS_KAE_RSA_H

#include "crypt_bn.h"
#include "bsl_params.h"
#include "bsl_errno.h"
#include "bsl_err_internal.h"
#include "crypt_algid.h"
#include "crypt_errno.h"
#include "crypt_rsa.h"

#include "wd.h"
#include "wd_rsa.h"

#define PARAMISNULL(a) (a == NULL || a->value == NULL)

typedef struct RSA_Para {
    BN_BigNum *n;
    BN_BigNum *e;
    BN_BigNum *d;
    BN_BigNum *p;
    BN_BigNum *q;
    BN_BigNum *dP;
    BN_BigNum *dQ;
    BN_BigNum *qInv;
    uint32_t bits;
} RSA_Para;

typedef enum {
    EMSA_PKCSV15 = 1,
    EMSA_PSS,
    RSAES_OAEP,
    RSAES_PKCSV15,
    RSA_NO_PAD,
    RSAES_PKCSV15_TLS,
} RSA_PadType;

typedef struct KAE_RSA_Ctx
{
    struct wd_queue                     queue;
    struct wd_queue_mempool*            pool;
    struct wcrypto_rsa_ctx_setup        setup;
    struct wcrypto_rsa_op_data          opData;
    void*                               rsaCtx;
    struct RSA_Para*                    para;
    struct wcrypto_rsa_pubkey*          pubKey;
    struct wcrypto_rsa_prikey*          prvKey;
    RSA_PadType                         padType;
} KAE_RSA_Ctx;

KAE_RSA_Ctx* KAE_RSA_NewCtx(void);

int32_t KAE_RSA_SetPara(KAE_RSA_Ctx* ctx, const BSL_Param *para);

int32_t KAE_RSA_GenKey(KAE_RSA_Ctx* ctx);

int32_t KAE_RSA_SetPrv(KAE_RSA_Ctx* ctx, const BSL_Param *para);

int32_t KAE_RSA_SetPub(KAE_RSA_Ctx* ctx, const BSL_Param *para);

int32_t KAE_RSA_GetPrv(KAE_RSA_Ctx* ctx, BSL_Param *para);

int32_t KAE_RSA_GetPub(KAE_RSA_Ctx* ctx, BSL_Param *para);

KAE_RSA_Ctx* KAE_RSA_DupCtx(KAE_RSA_Ctx* ctx);

int32_t KAE_RSA_Cmp(const KAE_RSA_Ctx *a, const KAE_RSA_Ctx *b);

int32_t KAE_RSA_Ctrl(KAE_RSA_Ctx* ctx, int32_t opt, void *val, uint32_t len);

int32_t KAE_RSA_SignData(KAE_RSA_Ctx* ctx, const uint8_t *data, uint32_t dataLen, uint8_t *sign, uint32_t *signLen);

int32_t KAE_RSA_VerifyData(KAE_RSA_Ctx* ctx, const uint8_t *data, uint32_t dataLen, uint8_t *sign, uint32_t signLen);

int32_t KAE_RSA_Sign(KAE_RSA_Ctx *ctx, int32_t algId, const uint8_t *data, uint32_t dataLen, uint8_t *sign, uint32_t *signLen);

int32_t KAE_RSA_Verify(KAE_RSA_Ctx *ctx, int32_t algId, const uint8_t *data, uint32_t dataLen, uint8_t *sign, uint32_t signLen);

int32_t KAE_RSA_Encrypt(KAE_RSA_Ctx* ctx, const uint8_t *data, uint32_t dataLen, uint8_t *out, uint32_t *outLen);

int32_t KAE_RSA_Decrypt(KAE_RSA_Ctx* ctx, const uint8_t *data, uint32_t dataLen, uint8_t *out, uint32_t *outLen);

void KAE_RSA_Free(KAE_RSA_Ctx* ctx);

#endif